\subsubsection{Win32}

\myparagraph{Неинициализированные данные в \ac{TLS}}

Одно из решений --- это добавить модификатор \TT{\_\_declspec( thread )} к глобальной переменной, 
и теперь она будет выделена в \ac{TLS} (строка 9):

\lstinputlisting[numbers=left,style=customc]{OS/TLS/win32/rand_uninit.c}

Hiew показывает что в исполняемом файле теперь есть новая PE-секция: \TT{.tls}.
% TODO1 hiew screenshot?

\lstinputlisting[caption=\Optimizing MSVC 2013 x86,style=customasmx86]{OS/TLS/win32/rand_x86_uninit.asm}

\TT{rand\_state} теперь в \ac{TLS}-сегменте и у каждого потока есть своя версия этой переменной.

Вот как к ней обращаться: загрузить адрес \ac{TIB} из FS:2Ch, затем прибавить дополнительный индекс 
(если нужно), затем вычислить адрес \ac{TLS}-сегмента.

Затем можно обращаться к переменной \TT{rand\_state} через регистр ECX, который указывает на свою
область в каждом потоке.

\myindex{x86!\Registers!FS}
Селектор \TT{FS:} знаком любому reverse engineer-у, он всегда указывает на \ac{TIB}, чтобы всегда можно было
загружать данные специфичные для текущего потока.

\myindex{x86!\Registers!GS}
В Win64 используется селектор \TT{GS:} и адрес \ac{TLS} теперь 0x58:

\lstinputlisting[caption=\Optimizing MSVC 2013 x64,style=customasmx86]{OS/TLS/win32/rand_x64_uninit.asm}

\myparagraph{Инициализированные данные в \ac{TLS}}

Скажем, мы хотим, чтобы в переменной \TT{rand\_state} в самом начале было какое-то значение, 
и если программист забудет инициализировать генератор, то \TT{rand\_state} все же будет инициализирована какой-то
константой (строка 9):

\lstinputlisting[numbers=left,style=customc]{OS/TLS/win32/rand_init.c}

Код ничем не отличается от того, что мы уже видели, но вот что мы видим в IDA:

\lstinputlisting[style=customasmx86]{OS/TLS/win32/rand_init_IDA.lst}

Там 1234 и теперь, во время запуска каждого нового потока, новый \ac{TLS} будет выделен для нового потока,
и все эти данные, включая 1234, будут туда скопированы.

Вот типичный сценарий:

\begin{itemize}
\item Запустился поток А. \ac{TLS} создался для него, 1234 скопировалось в \TT{rand\_state}.

\item Функция \TT{my\_rand()} была вызвана несколько раз в потоке А. \\
\TT{rand\_state} теперь содержит что-то неравное 1234.

\item Запустился поток Б. \ac{TLS} создался для него, 1234 скопировалось в \TT{rand\_state}, 
а в это же время, поток А имеет какое-то другое значение в этой переменной.
\end{itemize}

\myparagraph{\ac{TLS}-коллбэки}
\myindex{TLS!Коллбэки}

Но что если переменные в \ac{TLS} должны быть установлены в значения, которые должны быть подготовлены
каким-то необычным образом?

Скажем, у нас есть следующая задача:
программист может забыть вызвать функцию \TT{my\_srand()} для инициализации \ac{PRNG}, но генератор должен быть
инициализирован на старте чем-то по-настоящему случайным а не 1234.

Вот случай где можно применить \ac{TLS}-коллбэки.

Нижеследующий код не очень портабельный из-за хака, но тем не менее, вы поймете идею.

Мы здесь добавляем функцию (\TT{tls\_callback()}), которая вызывается \IT{перед} стартом процесса и/или потока.

Функция будет инициализировать \ac{PRNG} значением возвращенным функцией \TT{GetTickCount()}.

\lstinputlisting[style=customc]{OS/TLS/win32/rand_TLS_callback.c}

Посмотрим в IDA:

\lstinputlisting[caption=\Optimizing MSVC 2013,style=customasmx86]{OS/TLS/win32/rand_TLS_callback.lst}

TLS-коллбэки иногда используются в процедурах распаковки для запутывания их работы.

Некоторые люди могут быть в неведении что какой-то код уже был исполнен прямо перед \ac{OEP}.

